The present invention relates to system infrastructure and services that provide an object model or environment for hosting object-oriented component applications, and more particularly relates to extensibility of the object environment with added domain specific behaviors.
Object models, such as the Microsoft Component Object Model (xe2x80x9cCOMxe2x80x9d), define a standard structure of software objects that can be interconnected and collectively assembled into an application (which, being assembled from component objects, is herein referred to as a xe2x80x9ccomponent applicationxe2x80x9d). The objects are hosted in an execution environment created by system services, such as the object execution environments provided by COM, as well as system services added by Microsoft Object Linking and Embedding (xe2x80x9cOLExe2x80x9d), Microsoft Distributed Component Object Model (DCOM), and the Microsoft Transaction Server (xe2x80x9cMTSxe2x80x9d) systems. These systems expose services for use by component application objects in the form of application programming interfaces (xe2x80x9cAPIsxe2x80x9d), system-provided objects and system-defined object interfaces.
In accordance with object-oriented programming principles, the component application is a collection of object classes which each model real world or abstract items by combining data to represent the item""s properties with functions to represent the item""s functionality. More specifically, an object is an instance of a programmer-defined type referred to as a class, which exhibits the characteristics of data encapsulation, polymorphism and inheritance. Data encapsulation refers to the combining of data (also referred to as properties of an object) with methods that operate on the data (also referred to as member functions of an object) into a unitary software component (i.e., the object), such that the object hides its internal composition, structure and operation and exposes its functionality to client programs that utilize the object only through one or more interfaces. An interface of the object is a group of semantically related member functions of the object. In other words, the client programs do not access the object""s data directly, but must instead call functions on the object""s interfaces to operate on the data.
Polymorphism refers to the ability to view (i.e., interact with) two similar objects through a common interface, thereby eliminating the need to differentiate between two objects. Inheritance refers to the derivation of different classes of objects from a base class, where the derived classes inherit the properties and characteristics of the base class.
The object execution environments of the above mentioned COM, OLE, DCOM, and MTS systems have several behaviors towards component application objects that depend on locality or like environment aspects (hereafter referred to as xe2x80x9cdomainsxe2x80x9d) of the component application objects. The domains of a component application object in these environments include physical location (e.g., machine and process), isolation domains (e.g., process, user/kernel, security, transactions, auditing), synchronization domains (e.g., apartments, activities), object lifetime and identity domains (e.g., persistence, just-in-time activation, assemblies, per-client global and shared state), and representation domains (e.g., unicode/ANSI, 16/32-bit, locale, native/automation, Java/COM). For example, the OLE object execution environment has behaviors for object persistence and local/remote transparency whose operation on an object depends on the object""s location, e.g., machine and process. The MTS object execution environment has thread synchronization, automatic transactions, just-in-time object activation, declarative security and resource pooling behaviors that also are specific to an object""s locality or other environment aspects that pertain to the object.
Although COM provides certain domain-specific behaviors in its object execution environment, COM lacks any structure or mechanism to extend the environment with new domain-specific behaviors. One problem is that such behaviors rely for their implementation on services that must automatically impose themselves into many interactions between objects, such as at object instantiation, upon passing an interface pointer, and during calls (function invocations and returns), preferably without relying on any programming or action on the part of the objects.
A further complication is that COM has services that provide processing during certain of the interactions, yet does not provide any mechanism to extend the service to also provide processing of new domain-specific behaviors. For example, COM has an object instantiation service (i.e., the xe2x80x9cCoCreateInstance( )xe2x80x9d API) that performs processing for certain system-provided environment behaviors at instantiation time, such as local/remote transparency.
Yet another complication is that certain inter-objects interactions do not involve any system-provided services in COM. For example, a call between two objects in a same process generally is made using a direct reference. Thus, no system service is invoked and afforded an opportunity to process domain-specific behaviors during these interactions.
The more recent MTS system extends the object execution environment of COM to include a number of additional domain-specific behaviors, including the before-mentioned thread synchronization, automatic transactions, just-in-time object activation, declarative security and resource pooling behaviors. However, the methods and mechanisms used in the MTS system to extend the COM object execution environment again fail to provide a general environment extensibility solution.
More specifically, one way in which the MTS system adds automatic services to extend the COM object execution environment is to provide a separate object instantiation service (the xe2x80x9cIObjectContext::CreateInstance( )xe2x80x9d function) that performs processing for the MTS domain-specific behaviors during object instantiation. This MTS object instantiation service is layered over the object instantiation service of COM (i.e., the xe2x80x9cCoCreateInstance( )xe2x80x9d API). In other words, after its domain-specific behavior processing, the MTS xe2x80x9cIObjectContext::CreateInstance( )xe2x80x9d function invokes the xe2x80x9cCoCreateInstance( )xe2x80x9d API to complete object instantiation processing (and domain-specific behaviors of COM).
This approach of layering separate new object instantiation services over that of the base system, however, has a number of drawbacks. First, in order to gain the full benefit of the domain-specific behavior, the new object instantiation service must be used in place of the base system""s object instantiation service. This requires that the component application objects are rewritten to invoke the new service, or forgo the domain-specific behavior that the new service provides. In the MTS system for example, component application objects must be programmed to use the xe2x80x9cIObjectContext::CreateInstance( )xe2x80x9d function to create other component application objects. Otherwise, component application objects that are created via the xe2x80x9cCoCreateInstance( )xe2x80x9d API of the base COM system are not automatically placed in the same transaction as their creator, and do not have the full benefit of the MTS system""s automatic transactions behavior. In many cases (e.g., for all previously developed and deployed legacy component applications), it may be impossible to rewrite the component applications to use new object instantiation services, which makes the new behaviors unattainable for such component applications.
Second, repeated use of the layering approach to add domain-specific behaviors to an environment can lead to competing layered services proliferating haphazardly. As a consequence, object developers may be forced to choose among the domain-specific behaviors of the object execution environment according to which of the competing layered services their component application objects are programmed to invoke. For example, suppose a new threading model behavior is provided in the COM object execution environment by (in part) layering yet another object instantiation service (e.g., a xe2x80x9cCreateInNewThreadModelxe2x80x9d API) over the xe2x80x9cCoCreateInstance( )xe2x80x9d API. Component application developers would then have to choose whether to program their component application objects to use this new object instantiation service so as to avail the component application of the new threading model behavior, or program the objects to use the xe2x80x9cIObjectContext::CreateInstance( )xe2x80x9d function to gain the domain specific behaviors of the MTS system (while forgoing the new threading model behavior).
Due to these disadvantages, the layering approach by itself does not provide an acceptable general solution to extending an object execution environment to incorporate new domain-specific behaviors.
As mentioned above, another complication to implementing automatic services to provide environment-extending, domain-specific behaviors is that no system-provided services are involved in certain inter-object interactions, such as calls within a same process in COM. The approach of the MTS system to overcome this difficulty is to replace the direct reference to an object with an indirect reference via a system-provided intermediary (termed a xe2x80x9csafe referencexe2x80x9d). The MTS system automatically provides the safe reference upon return from an object instantiation request, and on return from an interface query (e.g., using COM-defined xe2x80x9cQueryInterface( )xe2x80x9d function). However, an object is restricted from passing a direct interface pointer (e.g., to its own interfaces), and must first convert the direct interface to a safe reference via a call to a xe2x80x9cSafeRef( )xe2x80x9d API provided by the MTS system. The safe references of the MTS system also have the drawback that they provide processing for only certain domain-specific behaviors (those provided in the MTS system) during calls made using the safe reference. There is no provision made to allow processing for other domain-specific behaviors. So, repeating the safe reference approach for other domain-specific behaviors could again lead to a proliferation of competing types of xe2x80x9csafe references.xe2x80x9d
The MTS system also implicitly associates a system-provided context object with each component application object hosted in the MTS execution environment. The context object encapsulates certain properties (e.g., a creator identity, a transaction, an activity, and security properties) that establish a xe2x80x9ccontextxe2x80x9d for the component application object within the MTS execution environment, and control certain of the environment""s behaviors (e.g., automatic transactions, declarative security, etc.). However, the MTS object-context objects encapsulate properties specific to the domain-specific behaviors supported by the MTS system. Again, no structure is provided to readily extend the MTS object-context objects to support new domain-specific behaviors.
The present invention introduces contexts, policies, policy makers and activators that operate as general, extensible structure for automatic services to extend an object execution environment of an object-oriented system with domain-specific behaviors. According to an embodiment of the invention illustrated herein, independent aspects (e.g., threading model, declarative security, activity, transaction, etc.) of the object execution environment that are associated with objects are termed xe2x80x9cdomains.xe2x80x9d A group of one or more component application objects in the execution environment that share a common set of domains (i.e., are at an intersection of domains in the environment) are said to be in a xe2x80x9ccontext.xe2x80x9d The illustrated embodiment represents the context as a context object that contains an ordered list of context property objects. The context property objects represent the domains and may be shared by more than one context.
Policies are automatic services that trigger on calls between contexts to provide the extensible domain-specific behaviors in the execution environment. In the illustrated embodiment, policies are represented as policy objects. The policy objects act as sinks for context events that are delivered on calls between component application objects which cross context boundaries. The context events include call and return events on a client side of the cross-context call, and enter and leave events on a server side of the call. (The term xe2x80x9cclientxe2x80x9d is used to refer to the component application object making a call, whereas xe2x80x9cserverxe2x80x9d refers to the recipient of the call.) The policy objects thus implement the semantics of entering or leaving a domain.
As per conventional COM practice, an object makes calls to other objects using a reference to the other object. Where the other object is in the same context, the reference is a direct pointer to the other object. In the illustrated embodiment however, the reference is via a proxy whenever the other object is in another context. This proxy has a policy set, which is a collection of policy objects to which context events are delivered when a call is made using the reference. The policy set can include both client-side policy objects that are delivered call and return events, and server-side policy objects that are delivered enter and leave events. A policy may have policy objects on each side, which may exchange a buffer of data. Other events also can be delivered to the policy objects, such as xe2x80x9cAddRefPolicyxe2x80x9d and xe2x80x9cReleasePolicyxe2x80x9d events.
Typically, the policy set includes policy objects that provide domain-specific behaviors for the domains that differ between the client and server-side contexts. For example, where the client and server contexts have different apartments and transactions, the policy set may include policy objects that support behaviors for apartment threading and automatic transactions. Where the client and server contexts have the same apartment but different transactions, the policy set may include only policy objects for the automatic transactions behavior. The policy sets thus reflect domain differences between contexts.
The policy set of a reference to an object in another context is built using policy makers. The policy makers correspond to the properties of a context. In fact, the context property objects in the illustrated embodiment may also act as policy makers for the domains that they represent (in which case they also are termed xe2x80x9cpolicy maker objectsxe2x80x9d). At the time a client object obtains a reference to a server object (more specifically, at unmarshaling such a reference in the illustrated embodiment), a request is sent to each of the policy makers in both client and server contexts to contribute policies to the policy set. Typically, the policy maker does not add a policy to the policy set of the cross-context reference if both client and server contexts have the identical property. In this way, an optimal policy set is built for the cross-context reference that includes policy objects for just the domains that differ between the contexts. The policy maker can add itself as the policy object, so that the same object can act as the context property object, policy maker object and policy object for a domain.
The context of an object is initialized at the time of an object instantiation request using activators. An object instantiation service (e.g., the xe2x80x9cCoCreateInstance( )xe2x80x9d API) delegates responsibility for activation of the requested object in the correct context through a possibly distributed chain of activators. Activators in the chain can modify the context properties, then delegate on to a next activator. The activator chain can include custom activators specific to the requested object""s class, the client context, and context properties (i.e., domains), as well as system-provided default or general activators. In the illustrated implementation of the invention, custom activators can be supplied for a particular class of object to be invoked at each of plural activation stages for the context, apartment, process and machine. Further, the activators perform context initialization as a function of properties of the client context (i.e., that of the object that issued the instantiation request), as well as properties of the object class being instantiated (e.g., which may be set by configuration information registered for the class in the configuration database or registry of the operating system). Often, the activator chain simply chooses the client context as the context of the requested object. However, where one or more of the context properties are modified, the activators activate the requested object in another context or create a new context in which to activate the requested object, as appropriate.
Activators allow context initialization to be extended to account for extensions to contexts. For example, an activator can be added to the activator chain to properly initialize contexts for a new context property object, policy maker object and policy object that provide a new domain and domain-specific behavior in the object execution environment. Object instantiation requests can continue to be made directly to the object instantiation service, so that context initialization for the added domain-specific behavior occurs automatically as an object execution environment behavior.
Additional features and advantages of the invention will be made apparent from the following detailed description of an illustrated embodiment which proceeds with reference to the accompanying drawings.